/*
 * 功能：车辆服务类，提供车辆相关的业务逻辑操作
 * 作者：张杨(Sunny)
 * 日期： 2024/11/6 下午2:29
 */
package com.example.springboot.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.common.Result;
import com.example.springboot.entity.Car;
import com.example.springboot.entity.User;
import com.example.springboot.mapper.CarMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class CarService extends ServiceImpl<CarMapper, Car> {

    @Resource
    CarMapper carMapper;


    /**
     * 分页查询汽车信息，支持按品牌、型号和颜色进行筛选
     *
     * @param pageNum  当前页码
     * @param pageSize 每页显示的记录数
     * @param remark   备注（模糊查询）
     * @param number   车牌号（模糊查询）
     * @param brand    品牌（模糊查询）
     * @param model    类型（模糊查询）
     * @param state    状态（模糊查询）
     * @return 返回分页查询结果
     */
    public Page<Car> selectByPage(Integer pageNum, Integer pageSize, String remark, String number, String brand, String model, String state) {
        QueryWrapper<Car> queryWrapper = new QueryWrapper<Car>().orderByDesc("state");
        queryWrapper.like(StrUtil.isNotBlank(remark), "remark", remark);
        queryWrapper.like(StrUtil.isNotBlank(number), "number", number);
        queryWrapper.like(StrUtil.isNotBlank(brand), "brand", brand);
        queryWrapper.like(StrUtil.isNotBlank(model), "model", model);
        queryWrapper.like(StrUtil.isNotBlank(state), "state", state);
        return carMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
    }


    /**
     * 导出汽车信息到Excel文件
     *
     * @param number   车牌号（模糊查询）
     * @param remark   备注（模糊查询）
     * @param ids      汽车ID列表（精确查询）
     * @param response HTTP响应对象
     * @throws IOException 如果IO操作失败
     */
    public void exportData(String number, String remark, String ids, HttpServletResponse response) throws IOException {
        ExcelWriter writer = ExcelUtil.getWriter(true); // 创建Excel写入器
        List<Car> list; // 用于存储查询结果的列表
        QueryWrapper<Car> queryWrapper = new QueryWrapper<>(); // 创建查询条件包装器

        // 如果ids参数不为空，则按ID筛选数据
        if (StrUtil.isNotBlank(ids)) {
            List<Integer> idsArr1 = Arrays.stream(ids.split(",")).map(Integer::valueOf).collect(Collectors.toList());
            queryWrapper.in("id", idsArr1);
        } else {
            // 否则按车牌号或备注筛选数据
            queryWrapper.like(StrUtil.isNotBlank(number), "number", number);
            queryWrapper.like(StrUtil.isNotBlank(remark), "remark", remark);
        }
        list = carMapper.selectList(queryWrapper); // 执行查询
        writer.write(list, true); // 将查询结果写入Excel

        // 设置响应头，指定文件类型和文件名
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="
                + URLEncoder.encode("车辆信息表", "UTF-8") + ".xlsx");

        ServletOutputStream outputStream = response.getOutputStream(); // 获取响应输出流
        writer.flush(outputStream, true); // 将Excel数据刷新到输出流
        writer.close(); // 关闭写入器
        outputStream.flush(); // 刷新输出流
        outputStream.close(); // 关闭输出流
    }

    // 导入信息的方法
    @Transactional
    public Result importData(MultipartFile file) throws IOException {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        List<Car> carList = reader.readAll(Car.class);
        // 写入数据到数据库
        try {
            saveBatch(carList);
            return Result.success();
        } catch (Exception e) {
            return Result.error("数据批量导入错误");
        }
    }
}
